home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / smaltalk / st80_pr4.lha / st80_pre4 / MoDE / Comms-Shan.st < prev    next >
Text File  |  1993-07-24  |  9KB  |  322 lines

  1. RootMode subclass: #CoMode
  2.     instanceVariableNames: 'running eventQ isMaster eventSkt '
  3.     classVariableNames: 'EventSelectorTable '
  4.     poolDictionaries: ''
  5.     category: 'Comms-Shan'!
  6.  
  7.  
  8. !CoMode methodsFor: 'controller access'!
  9.  
  10. defaultControllerClass
  11.     ^CoController! !
  12.  
  13. !CoMode methodsFor: 'access'!
  14.  
  15. eventQ: aQueue
  16.     eventQ _ aQueue!
  17.  
  18. eventSkt: aSkt
  19.     eventSkt _ aSkt!
  20.  
  21. isMaster: aBool
  22.     isMaster _ aBool! !
  23.  
  24. !CoMode methodsFor: 'event handling'!
  25.  
  26. processAnEvent
  27.     | event transEvent |
  28.     isMaster
  29.         ifTrue: 
  30.             [event _ self eventQueue next.
  31.             (self containsPoint: event origin)
  32.                 ifTrue: 
  33.                     [transEvent _ event deepCopy origin: event origin - self insetDisplayBox origin.
  34.                     self sendEvent: transEvent]]
  35.         ifFalse: 
  36.             [event _ self receiveEvent.
  37.             "Change the relative coordinates back to the absolute    
  38.             ones."
  39.             event origin: event origin + self insetDisplayBox origin].
  40.     self processEvent: event.
  41.     event free! !
  42.  
  43. !CoMode methodsFor: 'send/receive events'!
  44.  
  45. receiveEvent
  46.     | event s buffer subBuf readSemi x y len needed start |
  47.     event _ MMSEvent new.
  48.     needed _ 9.
  49.     buffer _ String new: needed.
  50.     readSemi _ Semaphore new.
  51.     eventSkt waitForDataOn: readSemi.
  52.     start _ 1.
  53.     len _ eventSkt
  54.                 read: needed
  55.                 into: buffer
  56.                 at: start.
  57.     [len ~= needed]
  58.         whileTrue: 
  59.             [Transcript show: 'fragment '.
  60.             needed _ needed - len.
  61.             eventSkt waitForDataOn: readSemi.
  62.             start _ start + len.
  63.             len _ eventSkt
  64.                         read: needed
  65.                         into: buffer
  66.                         at: start].
  67.     s _ buffer copyFrom: 1 to: 1.
  68.     event selector: (EventSelectorTable at: s asNumber).
  69.     s _ buffer copyFrom: 2 to: 5.
  70.     x _ s asNumber.
  71.     s _ buffer copyFrom: 6 to: 9.
  72.     y _ s asNumber.
  73.     event origin: x @ y.
  74.     ^event!
  75.  
  76. sendEvent: event 
  77.     | s sIndex eIndex source |
  78.     s _ '000000000'.
  79.     s    replaceFrom: 1
  80.         to: 1
  81.         with: (EventSelectorTable keyAtValue: event selector) printString
  82.         startingAt: 1.
  83.     source _ event origin x printString.
  84.     sIndex _ 6 - source size.
  85.     eIndex _ 5.
  86.     s    replaceFrom: sIndex
  87.         to: eIndex
  88.         with: source
  89.         startingAt: 1.
  90.     source _ event origin y printString.
  91.     sIndex _ 10 - source size.
  92.     eIndex _ 9.
  93.     s    replaceFrom: sIndex
  94.         to: eIndex
  95.         with: source
  96.         startingAt: 1.
  97.     eventSkt write: s! !
  98.  
  99. !CoMode methodsFor: 'startUp/stopRunning'!
  100.  
  101. run
  102.     "Ordinary modes do not hae this loop.  Their event-fetching loops are  
  103.     merged with the polling loop."
  104.     "Shan March 7, 1989"
  105.  
  106.     | event |
  107.     running _ true.
  108.     [running]
  109.         whileTrue: 
  110.             [event _ self eventQueue next.
  111.             self processEvent: event.
  112.             event free].
  113.     super stopRunning!
  114.  
  115. startUp
  116.     "Since the application can become a slave or a master during 
  117.     execution, use the two processes mechanism for the environment 
  118.     control. "
  119.     "Shan March 7, 1989"
  120.  
  121.     CoSlaveStdSysView startUp: self!
  122.  
  123. stopRunning
  124.     eventSkt close.
  125.     running _ false.
  126.     "[(Delay forMilliseconds: 250) wait.
  127.     superView controller close] fork."
  128.     "This is for the slave to terminate.  Since it may never execute the controlTerminate message if the cursor never enter its area."
  129.     "isMaster ifFalse:[
  130.     superView controller controlTerminate]"! !
  131. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  132.  
  133. CoMode class
  134.     instanceVariableNames: ''!
  135.  
  136.  
  137. !CoMode class methodsFor: 'testing'!
  138.  
  139. startAsMaster: bool 
  140.     "CoMode startAsMaster: true"
  141.     "CoMode startAsMaster: false"
  142.     "CoSlaveStdSysController allInstances do: [:each| each closeAndUnschedule]"
  143.     
  144.     | coM sMode host service socket |
  145.     host _ FillInTheBlank request: 'Name of host? (blank for this one)'.
  146.     service _ FillInTheBlank request: 'Name of the service socket' initialAnswer: '9876'.
  147.     service isEmpty ifTrue: [^nil].
  148.     "Connect to socket."
  149.     socket _ Socket connectTo: service on: host.
  150.     socket isNil
  151.         ifTrue: 
  152.             [Transcript cr; show: 'Connection failed, please run the Echo Server process.'.
  153.             ^nil].
  154.     coM _ CoMode new.
  155.     sMode _ Simple newMode.
  156.     coM
  157.         addSubView: sMode
  158.         in: (0.1 @ 0.1 corner: 0.9 @ 0.9)
  159.         borderWidth: 1.
  160.     coM isMaster: bool.
  161.     coM eventSkt: socket.
  162.     coM startUp! !
  163.  
  164. !CoMode class methodsFor: 'initialize'!
  165.  
  166. initialize
  167.     "Set up the selector table"
  168.     "CoMode initialize"
  169.     EventSelectorTable _ Dictionary new.
  170.     EventSelectorTable at: 0 put: #unknowEvent.
  171.     EventSelectorTable at: 1 put: #leftButtonDown.
  172.     EventSelectorTable at: 2 put: #leftButtonUp.
  173.     EventSelectorTable at: 3 put: #middleButtonDown.
  174.     EventSelectorTable at: 4 put: #middleButtonUp.
  175.     EventSelectorTable at: 5 put: #rightButtonDown.
  176.     EventSelectorTable at: 6 put: #rightButtonUp.
  177.     EventSelectorTable at: 7 put: #cursorMove.! !
  178.  
  179. CoMode initialize!
  180.  
  181.  
  182. StandardSystemController subclass: #CoSlaveStdSysController
  183.     instanceVariableNames: ''
  184.     classVariableNames: ''
  185.     poolDictionaries: ''
  186.     category: 'Comms-Shan'!
  187. CoSlaveStdSysController comment:
  188. 'I detect the cursor actions.  When I should be active, I turn on the event generation, activate the rootModeProcess and then monitor the cursor action every 250 msec.  When I go off, I stop the event generation and suspend the rootModeProcess.'!
  189.  
  190.  
  191. !CoSlaveStdSysController methodsFor: 'basic control sequence'!
  192.  
  193. controlLoop
  194.     "Resume the process of events when enter; suspend it when leave."
  195.  
  196.     self isControlActive
  197.         ifTrue: 
  198.             [self eventQueue enable.
  199.             "If the rootModeProcess is in sleep, wake it up. This will enable two sessions of MMS running at the same time."
  200.             "(Processor includes: view rootModeProcess)
  201.                 ifTrue: [view rootModeProcessResume]" "This include method is in the printOut but not in the image.  Strange!!!!!!!!??"]
  202.         ifFalse: [^self].
  203.     [self isControlActive]
  204.         whileTrue: 
  205.             [Processor yield.
  206.             self controlActivity].
  207.     self eventQueue disable
  208.     "view rootModeProcessSuspend"! !
  209.  
  210. !CoSlaveStdSysController methodsFor: 'control defaults'!
  211.  
  212. controlActivity
  213.     "Put myself into sleep so that I consume as few unnecessary CPU 
  214.     cycles as possible."
  215.  
  216.     (Delay forMilliseconds: 250) wait! !
  217.  
  218. !CoSlaveStdSysController methodsFor: 'scheduling'!
  219.  
  220. open
  221.     "This is the place to start the event processing loop.  After the size of the view has been decided and right before the process is exec()ed.  I mean after the last statement of this method there is no return.  It is just like the exec() system call in C."
  222.  
  223.     view resize.
  224.     status _ #open.
  225.     view rootModeProcessResume. 
  226.      (Delay forMilliseconds: 250) wait.  "This is necessary for the rootModeProcess to 
  227. take control for a while.  Otherwise the whole thing won't run."
  228.     ScheduledControllers scheduleActive: self! !
  229.  
  230. MController subclass: #CoController
  231.     instanceVariableNames: ''
  232.     classVariableNames: 'CoController1ERD '
  233.     poolDictionaries: ''
  234.     category: 'Comms-Shan'!
  235.  
  236.  
  237. !CoController methodsFor: 'Event Handling'!
  238.  
  239. rightButtonDown
  240.     mode stopRunning.
  241.     ^true! !
  242. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  243.  
  244. CoController class
  245.     instanceVariableNames: ''!
  246.  
  247.  
  248. !CoController class methodsFor: 'initialize'!
  249.  
  250. ERDinit
  251.  
  252.     CoController1ERD _ super eventResponsesDict deepCopy.
  253.     CoController1ERD at: #rightButtonDown put: #self! !
  254.  
  255. !CoController class methodsFor: 'access'!
  256.  
  257. eventResponsesDict
  258.     ^CoController1ERD! !
  259.  
  260. StandardSystemView subclass: #CoSlaveStdSysView
  261.     instanceVariableNames: 'rootModeProcess '
  262.     classVariableNames: ''
  263.     poolDictionaries: ''
  264.     category: 'Comms-Shan'!
  265. CoSlaveStdSysView comment:
  266. 'This is the environment for the CoModes to reside.  It uses the two-process control mechanism to handle the control passing.'!
  267.  
  268.  
  269. !CoSlaveStdSysView methodsFor: 'controller access '!
  270.  
  271. defaultControllerClass
  272.     ^CoSlaveStdSysController! !
  273.  
  274. !CoSlaveStdSysView methodsFor: 'rootMode process control'!
  275.  
  276. rootModeProcess
  277.     ^rootModeProcess!
  278.  
  279. rootModeProcess: aProcess
  280.     rootModeProcess _ aProcess!
  281.  
  282. rootModeProcessResume
  283.     ^rootModeProcess resume!
  284.  
  285. rootModeProcessSuspend
  286.     ^rootModeProcess suspend!
  287.  
  288. rootModeProcessTerminate
  289.     ^rootModeProcess terminate! !
  290.  
  291. !CoSlaveStdSysView methodsFor: 'initialize-release'!
  292.  
  293. release
  294.     "This method will be sent by the 
  295.     StandardSystemController>controlTerminate when the CoSlaveStdSysView (a 
  296.     StandardSystemView) which contains the RootMode is closed.  This 
  297.     means turn down the whole event driven mechanism."
  298.  
  299.     super release.
  300.     self eventQueue disable.
  301.     rootModeProcess terminate! !
  302. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  303.  
  304. CoSlaveStdSysView class
  305.     instanceVariableNames: ''!
  306.  
  307.  
  308. !CoSlaveStdSysView class methodsFor: 'MMS start up'!
  309.  
  310. startUp: aRootMode 
  311.     "Set up the environment for the aRootMode."
  312.     "Set up the InputState1 to generate events"
  313.  
  314.     | mmsTopView rootModeProc |
  315.     InputState1 replaceSystemInputState.
  316.     mmsTopView _ CoSlaveStdSysView new.
  317.     mmsTopView addSubView: aRootMode.
  318.     mmsTopView label: 'CoMMS'.
  319.     mmsTopView minimumSize: 400 @ 300.
  320.     rootModeProc _ [aRootMode run] newProcess.
  321.     mmsTopView rootModeProcess: rootModeProc.
  322.     mmsTopView controller open! !